{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3f7dcfc3",
   "metadata": {},
   "source": [
    "---------------\n",
    "* 记录人：hj\n",
    "* 时间：21-12-02\n",
    "* week14\n",
    "* 参考文档：\n",
    "> 1.[python官方文档](https://python/org)  \n",
    "> 2.[老师的gitee](https://gitee.com/xzhichao/python)  \n",
    "> 3.[老师的博客](https://www.cnblogs.com/xuzhichao)  \n",
    "---------------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e22ecb58",
   "metadata": {},
   "source": [
    "# 1.函数\n",
    "## 1.定义\n",
    "> 1.数学：     f(x) = ax+b\n",
    "\n",
    "> 2.python: def fib(x):\n",
    "\n",
    "> 3.编程思维 vs 数学思维\n",
    "\n",
    ">> 1.函数可以被定义名称，定义的关键字 <font style=\"color:red\">**def**</font>  \n",
    ">> 2.数学思维是写在同一行的（定义函数 和 运算公式），面向对象编程中 函数写多行，定义函数为单独一行   \n",
    ">> 3.数学函数一般没有注释，而编程过程中，一般需要对函数进行注释描述（docstring,p151）  \n",
    ">> 4.数学中：ax + b是计数公式，而编程中，我们将函数的内容成为**函数体**，函数体要有一定的**缩进**  \n",
    ">> 5.数学函数执行，将参数带入公式，而编程中函数执行，将参数带入函数体  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0e28393",
   "metadata": {},
   "source": [
    "## 2.关于函数更多的定义"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4083f80",
   "metadata": {},
   "source": [
    "> 1.函数的参数  \n",
    ">> 1,形式参数  \n",
    ">> 2.实际参数  \n",
    ">> 3.默认参数  \n",
    ">> 4.位置参数  \n",
    ">> 5.关键字参数  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c1d7f39",
   "metadata": {},
   "source": [
    "# 2.函数的定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a90a6be",
   "metadata": {},
   "outputs": [],
   "source": [
    "#1.定义的函数\n",
    "#def:定义函数的关键字\n",
    "#flb：函数名\n",
    "#(n)：定义函数的参数\n",
    "#\"\"\"  \"\"\"：文档描述 : 与使用者进行 交互的唯一途径\n",
    "#代码块：\n",
    "#     a, b = 0, 1\n",
    "#     while a < n:\n",
    "#        print(a, end=' ')\n",
    "#         a, b = b, a+b\n",
    "#     print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d09f82c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "#斐波那切数列：0,1,1,2,3,5,8,13,21,34 ...\n",
    "def fib(x):\n",
    "    \"\"\"列出指定x以内的斐波那切数列\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < x: \n",
    "        print(a,end=\" \")\n",
    "        a,b = b,a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f6f6e6f2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 "
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7173d4c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "#实践：写一个函数，这个函数可以打印“你好，xx同学”\n",
    "def hello():\n",
    "    \"\"\"打印 你好，海静同学\"\"\"\n",
    "    print(\"你好，海静同学\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b37d0170",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好，海静同学\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e2431127",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello(name):\n",
    "    \"\"\"打印 你好，海静同学\"\"\"\n",
    "    print(\"你好，%s同学~\"%(name))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0679f10e",
   "metadata": {},
   "source": [
    "> 2.调用函数/使用函数  \n",
    ">> a.函数名（参数）  \n",
    ">> b.参数可以不存在  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "802075e3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好，hj同学~\n"
     ]
    }
   ],
   "source": [
    "hello(\"hj\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f1009c74",
   "metadata": {},
   "outputs": [],
   "source": [
    "#回顾与思考\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b058612a",
   "metadata": {},
   "outputs": [],
   "source": [
    "time.sleep(3)#sleep()需要给定一个时间（int）参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "268a5a44",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=3, tm_hour=15, tm_min=22, tm_sec=33, tm_wday=4, tm_yday=337, tm_isdst=0)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "time.localtime()#不需要给定参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "3149ace5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function localtime in module time:\n",
      "\n",
      "localtime(...)\n",
      "    localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n",
      "                              tm_sec,tm_wday,tm_yday,tm_isdst)\n",
      "    \n",
      "    Convert seconds since the Epoch to a time tuple expressing local time.\n",
      "    When 'seconds' is not passed in, convert the current time instead.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(time.localtime)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa8882a6",
   "metadata": {},
   "source": [
    "> 3.函数的优势\n",
    ">> 1.可以重复使用相同的功能，避免重复造轮子\n",
    ">> 2.使用者可以不了解函数本身，只需要清楚如何使用即可\n",
    ">> 3.使用/调用方便，只需要清楚传递的 函数名及参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5679419f",
   "metadata": {},
   "source": [
    "# 3.函数的参数\n",
    "形式参数（形参））：形式参数，不是实际存在的，是虚拟变量。在定义函数和函数体的时候使用形参，目的是在函数调用时接收实参"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21aaae10",
   "metadata": {},
   "source": [
    "> 1.形式参数  \n",
    ">> a.在**定义**函数的时候定义的参数  \n",
    ">> b.形式参数不占用内存  \n",
    "\n",
    "> 2.实际的参数（实参）:实际参数，调用函数时传递给函数的参数，可以是常量、变量，表达式，函数，传给形参  \n",
    ">> a.在**调用**函数的时候传递的参数  \n",
    ">> b.调用函数时，形式参数分配空间，传递实际参数，执行函数内容  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "7cec0ac4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 课本函数实践实例：\n",
    "def search4vowels(word):\n",
    "    \"\"\"显示文本中出现的元音之母有哪些  \n",
    "    \n",
    "       word是文本信息，请输入正确的文本给word  \n",
    "    \"\"\"\n",
    "    vowels = set(\"aeiou\")\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6ddefcfa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"hjkgfffddsef\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "a608623d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search4vowels in module __main__:\n",
      "\n",
      "search4vowels(word)\n",
      "    显示文本中出现的元音之母有哪些  \n",
      "    \n",
      "    word是文本信息，请输入正确的文本给word\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(search4vowels)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "571e555a",
   "metadata": {},
   "source": [
    "> 形参：word   \n",
    "> 实参：hjkgfffddsef  \n",
    "\n",
    "**形参：形式参数，不是实际存在的，是虚拟变量。在定义函数和函数体的时候使用形参，目的是在函数调用时接收实参**  \n",
    "\n",
    "**实参：实际参数，调用函数时传递给函数的参数，可以是常量、变量，表达式，函数，传给形参**  \n",
    "\n",
    "**区别：形参是虚拟的，不占用空间，形参变量只有在被调用时才分配内存单元，实参是一个变量，占用内存空间，数据传递单向，实参传给形参，不能倒过来.**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0976f4d",
   "metadata": {},
   "source": [
    "* 在多个参数的情景下\n",
    "\n",
    "> 1.位置参数(positional argument)  \n",
    ">> 在形式参数的定义中，有一定的先后顺序  \n",
    ">> 在调用函数时，要考虑形参的先后顺序  \n",
    ">> 调用函数时，不仅要考虑参数位置，还需要考虑形式参数的个数  \n",
    "\n",
    "> 2.关键字参数  \n",
    ">> 1.在调用函数时，关键字参数可以不考虑形式参数的位置  \n",
    "\n",
    "> 3.默认参数    \n",
    ">> 1.调用函数时，可以省略传递的参数信息  \n",
    ">> 2.调用函数时，如果给默认参数赋值，会替换默认参数的结果  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "aa76eddf",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(pet_name,animal_type):\n",
    "     \"\"\"显示宠物信息\"\"\"\n",
    "     print(\"\\nI have a \" + animal_type + \".\")\n",
    "     print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "aedc577b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a 豆豆.\n",
      "My 豆豆's name is Dog.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"豆豆\")#错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "898b34c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"dog\")#正确"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "3e6cda21",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 1 required positional argument: 'animal_type'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-19-7b9959e7e395>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"豆豆\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() missing 1 required positional argument: 'animal_type'"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "1fd47528",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "My cat's name is 微积分.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(animal_type=\"cat\",pet_name=\"微积分\")#在调用函数时，关键字参数可以不考虑形式参数的位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "5f1c1e1d",
   "metadata": {},
   "outputs": [],
   "source": [
    "#默认参数\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "     \"\"\"显示宠物信息\"\"\"\n",
    "     print(\"\\nI have a \" + animal_type + \".\")\n",
    "     print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "5949e11a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "My cat's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"cat\")# 默认参数，在调用参数时，可以省略传递的参数信息，如果给\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8990ce75",
   "metadata": {},
   "source": [
    "### 参数的注意事项"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8102d420",
   "metadata": {},
   "source": [
    "> 1.位置参数和关键字参数同时使用（调用函数）  \n",
    ">> 1.positional argument follows keyword argument（关键字参数均应该放在位置参数之后）  \n",
    ">> 2.只要满足1的条件，剩余的关键字参数（多个）不考虑先后顺序\n",
    "\n",
    "> 2.非默认参数和默认参数同时使用（定义函数)    \n",
    ">> 1.non-default argument follows default argument（默认参数均应该放在非默认参数之后）   \n",
    ">> 2.只要满足1的条件，剩余的默认参数（多个）不考虑先后顺序  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "817501be",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,y,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "7c070e5e",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-22-489fdb94d38c>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-22-489fdb94d38c>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    test(5,y=3,2)\u001b[0m\n\u001b[1;37m               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "# 实践1：\n",
    "test(5,y=3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "7cbac67f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "3\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 实践2：\n",
    "test(5,3,z = 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "a5f4acd6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "# 实践3：\n",
    "test(5,z=3,y=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "2ee469c7",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-26-eac1f1ed18cb>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-26-eac1f1ed18cb>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    def test(x,y=1,z):\u001b[0m\n\u001b[1;37m             ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "# 测试2：\n",
    "def test(x,y=1,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "38d3037f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,z,y=1):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "accd4c72",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
